// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Linq.Expressions;

namespace SnapObjects.Data
{
    internal class PocoModelFactory<TModel> : IModelFactory<TModel>
    {
        private readonly Func<TModel> _createFn;
        private readonly IModelAccessor<TModel> _accessor;
        private readonly IModelValidator<TModel> _validator;

        public PocoModelFactory(Type modelType)
        {
            _createFn = Expression
                .Lambda<Func<TModel>>(Expression.New(modelType)).Compile();

            _accessor = this.CreateModelAccessor(modelType);
            _validator = this.CreateModelValidator(modelType);
        }

        protected virtual IModelAccessor<TModel> CreateModelAccessor(Type modelType)
        {
            return new PocoModelAccessor<TModel>(this, modelType);
        }

        protected virtual IModelValidator<TModel> CreateModelValidator(Type modelType)
        {
            return new PocoModelValidator<TModel>();
        }

        public TModel Create()
        {
            return _createFn();
        }

        public IModelAccessor<TModel> GetAccessor()
        {
            return _accessor;
        }

        public IModelValidator<TModel> GetValidator()
        {
            return _validator;
        }
    }
}
